package org.xlp.db.xml;

import org.xlp.db.xml.ele.SQLEle;

import java.io.File;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 异步处理sql配置文件应用
 * Create by xlp on 2023/10/19
 * @version 1.0
 * @author xlp
 */
public class AsyncSQLXmlContextApplication extends SQLXmlContextApplication{
    /**
     * 标记文件是否解析完成
     */
    private volatile AtomicBoolean parseCompleted = new AtomicBoolean(true);

    /**
     * 构造函数
     */
    public AsyncSQLXmlContextApplication() {}

    /**
     * 构造函数
     *
     * @param chainFactory {@link SQLXmlFileHandlerChain} 对象创建工厂
     */
    public AsyncSQLXmlContextApplication(ISQLXmlFileHandlerChainFactory chainFactory) {
        super(chainFactory);
    }

    /**
     * 解析sql xml配置文件路径
     *
     * @param filePath sql xml配置文件路径
     * @throws IllegalArgumentException 假如参数不是xml文件路径，则抛出该异常
     * @throws NullPointerException     假如参数为null或""，则抛出该异常
     */
    @Override
    public void parseFile(String filePath) {
        checkParseCompleted();
        parseCompleted.set(false);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    _parseFile(filePath);
                } finally {
                    parseCompleted.set(true);
                }
            }
        }, AsyncSQLXmlContextApplication.class.getName() + "sql语句配置文件解析线程(文件)").start();
    }

    /**
     * 解析sql xml配置文件路径
     *
     * @param filePath sql xml配置文件路径
     * @throws IllegalArgumentException 假如参数不是xml文件路径，则抛出该异常
     * @throws NullPointerException     假如参数为null或""，则抛出该异常
     */
    private void _parseFile(String filePath) {
        super.parseFile(filePath);
    }

    /**
     * 解析给定的目录下所有的sql xml配置文件
     *
     * @param directory sql xml配置文件目录
     * @throws IllegalArgumentException 假如参数不是文件目录，则抛出该异常
     * @throws NullPointerException     假如参数为null，则抛出该异常
     */
    @Override
    public void parseDirectory(File directory) {
        checkParseCompleted();
        parseCompleted.set(false);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    _parseDirectory(directory);
                } finally {
                    parseCompleted.set(true);
                }
            }
        }, AsyncSQLXmlContextApplication.class.getName() + "sql语句配置文件解析线程(目录)").start();
    }

    /**
     * 解析给定的目录下所有的sql xml配置文件
     *
     * @param directory sql xml配置文件目录
     * @throws IllegalArgumentException 假如参数不是文件目录，则抛出该异常
     * @throws NullPointerException     假如参数为null，则抛出该异常
     */
    private void _parseDirectory(File directory) {
        super.parseDirectory(directory);
    }

    /**
     * 获取通过sql语句配置文件解析出的所有SQLEle对象
     *
     * @return
     */
    @Override
    public Map<String, SQLEle> getSqlEleMap() {
        //checkParseCompleted();
        awaitCompleting();
        return super.getSqlEleMap();
    }

    /**
     * 更据Id获取相应的{@link SQLEle}对象
     *
     * @param parentId {@link SQLsElementInfo}的id值
     * @param id       {@link SQLEle}的id值
     * @return {@link SQLEle}对象
     * @throws NullPointerException 假如参数为null或""，则抛出该异常
     * @see SQLsElementInfo
     * @see SQLEle
     */
    @Override
    public SQLEle getSqlEle(String parentId, String id) {
        //checkParseCompleted();
        awaitCompleting();
        return super.getSqlEle(parentId, id);
    }

    /**
     * 检查文件sql语句配置文件是否解析完成
     */
    private void checkParseCompleted(){
        if (!parseCompleted.get()){
            throw new SQLXmlFileNotParseCompletedException("sql语句配置文件还未解析完，请稍后在使用！");
        }
    }

    /**
     * 等待执行完成
     */
    private void awaitCompleting(){
        while (!parseCompleted.get()){}
    }
}
